package com.mini.controller;

import com.alibaba.fastjson.JSON;
import com.mini.client.cache.CacheMnsClient;
import com.mini.common.annotation.AutoLog;
import com.mini.common.config.CheckLogin;
import com.mini.common.config.WebAppConfigurer;
import com.mini.es.service.EsBusinessStudentOrderInfoService;
import com.mini.mysql.model.BusinessTeacherInfo;
import com.mini.mysql.service.BusinessTeacherInfoService;
import com.mini.mysql.service.MnsService;
import com.mini.task.TaskAsyncMiniOrderDataServiceImpl;
import com.mini.vo.BusinessResult;
import com.mini.vo.MemberDataCondition;
import com.mini.vo.MemberDataVO;
import com.mini.vo.PageResultWithTotalVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zl
 * @version 1.0
 * @date Created in 2020/2/6
 */
@RestController
@RequestMapping("attn/memberData")
@Slf4j
@Api(tags = "成员汇总数据")
public class MemberDataController {

    @Autowired
    private CacheMnsClient cacheMnsClient;

    @Autowired
    private TaskAsyncMiniOrderDataServiceImpl taskAsyncDataService;
    @Autowired
    private EsBusinessStudentOrderInfoService esBusinessStudentOrderInfoService;
    @Autowired
    private MnsService mnsService;
    @Autowired
    private BusinessTeacherInfoService businessTeacherInfoService;

    @CheckLogin
    @AutoLog
    @PostMapping(value = "/select")
    @ApiOperation(value = "成员汇总数据", notes = "成员汇总数据")
    public BusinessResult<PageResultWithTotalVO<MemberDataVO>> teacherOptions(@RequestBody MemberDataCondition condition) {

        //搜索相关-过滤查询
        List<MemberDataVO> memberData = esBusinessStudentOrderInfoService.summaryDataByUser(changeCondition(condition));
        //搜索相关-特殊处理，如果搜索类型，是按组分类，且搜索条件中带有MemberDataController用户信息，按照用户所在组进行搜索，然后按运营组分类统计
        if (CollectionUtils.isNotEmpty(condition.getUserIds()) && MemberDataCondition.selectType.GROUP.code == condition.getSelectType()) {
            Set<Integer> groupIds = condition.getUserIds().stream().map(userId -> {
                BusinessTeacherInfo teacher = businessTeacherInfoService.findByTeacherId((long) userId);
                return Objects.nonNull(teacher) ? (int) (long) teacher.getGroupId() : null;
            }).filter(Objects::nonNull).collect(Collectors.toSet());
            condition.setGroupIds(groupIds);
            condition.setUserIds(Collections.EMPTY_SET);
        }

        //搜索相关-组和运营专员通过代码过滤的方式进行查询，提高性能
        memberData = memberData.stream().filter(order -> {
            if (CollectionUtils.isNotEmpty(condition.getUserIds()) && !condition.getUserIds().contains(order.getTeacherId())) {
                return false;
            } else {
                BusinessTeacherInfo teacher = businessTeacherInfoService.findByTeacherId((long) order.getTeacherId());
                if (Objects.isNull(teacher)) {
                    return false;
                }
                order.setTeacherName(teacher.getTeacherName());
                order.setGroupId((int) (long) teacher.getGroupId());
            }
            if (CollectionUtils.isNotEmpty(condition.getGroupIds()) && !condition.getGroupIds().contains(order.getGroupId())) {
                return false;
            }
            return true;
        }).sorted(Comparator.comparing(MemberDataVO::getTeacherId)).collect(Collectors.toList());

        //结果处理-如果查询结果维度为组，进行分组处理
        if (MemberDataCondition.selectType.GROUP.code == condition.getSelectType()) {
            memberData = memberData.stream()
                    .collect(Collectors.groupingBy(MemberDataVO::getGroupId))
                    .entrySet().stream().map(m -> {
                        MemberDataVO groupSummary = MemberDataVO.totalSummary(m.getValue());
                        groupSummary.setGroupId(m.getKey());
                        groupSummary.setChildren(m.getValue());
                        return groupSummary;
                    }).sorted(Comparator.comparing(MemberDataVO::getGroupId)).collect(Collectors.toList());
        }

        //结果处理-ES中分组查询不能分页，这里手动分页
        int skip = condition.getPageSize() * (condition.getPageNumber() - 1);
        List<MemberDataVO> rows = memberData.stream().skip(skip).limit(condition.getPageSize()).collect(Collectors.toList());
        PageResultWithTotalVO<MemberDataVO> page = new PageResultWithTotalVO<>(memberData.size(), rows, MemberDataVO.totalSummary(memberData));

        //结果处理-数据处理，对业务数据进行计算，小数点位数进行处理，运营组信息进行完善
        if (Objects.nonNull(page.getTotalRecord())) {
            page.getTotalRecord().fillData();
        }
        page.getRows().forEach(o -> {
            if (Objects.nonNull(o.getGroupId())) {
                String groupName = cacheMnsClient.getDeptFullName(WebAppConfigurer.getSign(), (long) o.getGroupId());
                o.setDeptName(groupName);
            }
            o.fillData();
            if (CollectionUtils.isNotEmpty(o.getChildren())) {
                o.getChildren().forEach(child -> {
                    child.fillData();
                    child.setDeptName(o.getDeptName());
                });
            }
        });
        return BusinessResult.createSuccessInstance(page);
    }

    private MemberDataCondition changeCondition(MemberDataCondition condition) {

        if (!CollectionUtils.isEmpty(condition.getDeptIds())) {
            condition.setGroupIds(mnsService.findGroupCondition(condition.getDeptIds(), condition.getUserId()).stream().map(id -> Integer.parseInt(id.toString())).collect(Collectors.toSet()));
        }

        Set<Long> userIds = mnsService.scopedOperationUserIds(condition.getUserId());
        if (CollectionUtils.isEmpty(condition.getGroupIds()) && CollectionUtils.isEmpty(condition.getUserIds()) && CollectionUtils.isNotEmpty(userIds)) {
            condition.setUserIds(userIds.stream().map(id -> Integer.parseInt(id.toString())).collect(Collectors.toSet()));
        }
        log.debug("MemberDataCondition={}", JSON.toJSONString(condition));
        return condition;
    }


}
